package br.com.pfm.dao.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;

import br.com.pfm.dao.FaturaDao;
import br.com.pfm.persistence.model.Fatura;
import br.com.pfm.persistence.model.Instituicao;
import br.com.pfm.vo.GastoPorInstituicao;

@Repository
public class FaturaDaoImpl implements FaturaDao{

	@PersistenceContext(unitName="pfm")
    private EntityManager em;
	
	@Override
	public void adiciona(Fatura fatura) {
		em.persist(fatura);
	}

	@Override
	public Fatura getFatura(Instituicao instituicao, Date dtVencimento) {
		
		Query query = em
				.createQuery("SELECT f From Fatura as f WHERE f.instituicao.id = :pIdInstituicao AND f.dtVencimento = :pDtVencimento");
		
		query.setParameter("pIdInstituicao", instituicao.getId());
		query.setParameter("pDtVencimento", dtVencimento);
		
		try{
			Fatura fatura = (Fatura) query.getSingleResult();
			return fatura;
		}catch(NoResultException e){
			return null;			
		}		
	}
	
	@Override
	public ArrayList<Fatura> getDadosList(ArrayList<Fatura> faturas) {
		ArrayList<Fatura> novaLista = new ArrayList<Fatura>();
		
		for(Fatura fatura : faturas){
			Query query = em
					.createQuery("SELECT f FROM Fatura as f WHERE f.instituicao.id = :pIdInstituicao AND f.dtVencimento = :pDtVencimento");
			
			query.setParameter("pIdInstituicao", fatura.getInstitucao().getId());
			query.setParameter("pDtVencimento", fatura.getDtVencimento());
			
			Fatura novaFatura = null;
			
			try{
				novaFatura = (Fatura) query.getSingleResult();
			}catch(NoResultException e){
				em.persist(fatura);
				novaFatura = fatura;
			}finally{
				novaLista.add(novaFatura);
			}			
		}
		return novaLista;
	}

	@Override
	public void atualiza(Fatura fatura) {
		em.merge(fatura);
	}

	@Override
	public ArrayList<Fatura> getList(int idInstituicao) {
		
		Query query = em
				.createQuery("SELECT f FROM Fatura as f WHERE f.instituicao.id = :pIdInstituicao ORDER BY f.dtVencimento DESC");
		
		query.setParameter("pIdInstituicao", idInstituicao);
		
		@SuppressWarnings("unchecked")
		ArrayList<Fatura> faturas = (ArrayList<Fatura>) query.getResultList();
		
		return faturas;
	}

	@Override
	public Fatura getFaturaById(int idFatura) {
		
		Fatura fatura = em.find(Fatura.class, idFatura);
		return fatura;
	}
	
	//@SuppressWarnings("unchecked")
	@Override
	public List<GastoPorInstituicao> getGastoPorInstituicao(){
		//String sql = "SELECT I.nm_instituicao AS nome, SUM(F.valor_fatura) AS valorFatura FROM PFM_fatura as F join PFM_instituicao I on I.id_instituicao = F.id_instituicao GROUP BY I.id_instituicao";
		Query query = em
				.createQuery("SELECT F.instituicao.nome AS nome,  SUM(F.valorFatura) AS valorFatura FROM Fatura as F GROUP BY F.instituicao.id");
		 
		@SuppressWarnings("unchecked")
		List<Object[]> results = query.getResultList();
		List<GastoPorInstituicao> gastos = new ArrayList<GastoPorInstituicao>();
				
		System.out.println("in for");
		for(int i = 0; i < results.size(); i++){
			GastoPorInstituicao gasto = new GastoPorInstituicao();
			gasto.setNm_instituicao((String) results.get(i)[0]);
			gasto.setValor_fatura((long) results.get(i)[1]);
			
			gastos.add(gasto);
		}
		System.out.println("out for");
	
		return gastos;
	}

	@Override
	public List<Fatura> getGastoNoMes(int mes, int ano) {
		Query query = em.createQuery("SELECT F FROM Fatura AS F WHERE MONTH(F.dtVencimento) = :pMes AND YEAR(F.dtVencimento) = :pAno GROUP BY F.instituicao.id");

		
		query.setParameter("pMes",mes);
		query.setParameter("pAno",ano);
		
		@SuppressWarnings("unchecked")
		List<Fatura> rs = query.getResultList(); 
				
		return rs;
	}
	
	@Override
	public long getConsumoNoMes(int mes, int ano){
		Query query = em.createQuery("SELECT SUM(F.valorFatura) FROM Fatura AS F WHERE MONTH(F.dtVencimento) = :pMes AND YEAR(F.dtVencimento) = :pAno");
		
		query.setParameter("pMes",mes);
		query.setParameter("pAno",ano);
		
		@SuppressWarnings("rawtypes")
		List results = query.getResultList();
		
	
		return (long) results.get(0);
	}
}
